package me.yricky.alia

import androidx.compose.ui.res.useResource
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import me.yricky.alia.appAbilities.CmdManager
import me.yricky.alia.appAbilities.KtsEngineFactory
import me.yricky.alia.arcane.Arcane
import me.yricky.alia.res.StringRes
import me.yricky.alia.ui.WindowInst
import me.yricky.alia.ui.gdsStructPage.GDSStructPageFactory
import me.yricky.alia.utils.command.Session
import me.yricky.alia.utils.safe
import javax.script.ScriptEngine
import javax.script.ScriptEngineManager

/**
 * @author Yricky
 * @date 2022/1/27
 */
object App{
    data class AppState(
        val activeWindows:Set<WindowInst> = emptySet(),
        val activeArcane:List<Arcane> = emptyList(),
        val exitAction:()->Unit = {},
    )
    private val _appState: MutableStateFlow<AppState> = MutableStateFlow(AppState())
    val appState = _appState.asStateFlow()

    data class Res(
        val str:StringRes = StringRes()
    )
    private val _res: MutableStateFlow<Res> = MutableStateFlow(Res())
    val res = _res.asStateFlow()

    val internalOpenMethods:Map<String,(String)->Unit> = mapOf(
        Pair("GDS"){ openGDS(it) },
        Pair("KTS"){ execScript(it) }
    )
    private val backgroundScope = CoroutineScope(Dispatchers.Default)
    val cmdManager:CmdManager by lazy{ CmdManager() }



    private fun openGDS(path:String){
        addWindow(
            GDSStructPageFactory.getWindowInst(path)
        )
    }



    fun addWindow(window:WindowInst){
        _appState.value = _appState.value.copy(
            activeWindows = _appState.value.activeWindows.plus(
                window
            )
        )
    }

    fun removeWindow(window: WindowInst){
        _appState.value = _appState.value.copy(
            activeWindows = _appState.value.activeWindows.minus(window)
        )
    }


    fun setExitAction(action:()->Unit){
        _appState.value = _appState.value.copy(
            exitAction = action
        )
    }
    private fun execScript(
        path: String,
        session: Session = cmdManager.defaultSession
    ){
        backgroundScope.launch{
            session.apply {
                o.println()
                o.println("----------Execute a script----------")
                o.println("File:$path")
                safe {
                    cmdManager.handle("kts $path",session)
                }
                o.println("----------      Done      ----------")
                o.print(">")
            }
        }
    }

    val path:String get() =System.getProperty("java.class.path")


    val scriptEngine: ScriptEngine by lazy{
        (ScriptEngineManager().getEngineByExtension("kts") ?:
        KtsEngineFactory().scriptEngine).also { se->
            backgroundScope.launch {
                safe {
                    useResource("kts/init.kts"){
                        se.eval(it.reader())
                    }
                }
            }
        }
    }

}